package com.medical.literature.recognition.service.impl;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.medical.literature.recognition.service.KeywordExtractionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 关键词提取服务实现类
 */
@Service
public class KeywordExtractionServiceImpl implements KeywordExtractionService {
    
    // 手动添加log变量
    private static final Logger log = LoggerFactory.getLogger(KeywordExtractionServiceImpl.class);
    
    // 医学相关词性标记
    private static final Set<String> MEDICAL_POS = new HashSet<String>(Arrays.asList("n", "nz", "v", "a", "i", "j", "x"));
    
    // 停用词列表（简化版）
    private static final Set<String> STOP_WORDS = new HashSet<String>(Arrays.asList(
        "的", "了", "在", "是", "我", "有", "和", "就", "不", "人", "都", "一", "一个",
        "上", "也", "很", "到", "说", "要", "去", "你", "会", "着", "没有", "看",
        "好", "自己", "这", "那", "个", "们", "能", "这个", "可以", "为", "但是",
        "and", "or", "the", "of", "to", "in", "for", "with", "on", "at", "by",
        "from", "as", "an", "be", "this", "that", "which", "were", "been", "their"
    ));
    
    // 医学关键词字典（简化版）
    private static final Set<String> MEDICAL_KEYWORDS = new HashSet<String>(Arrays.asList(
        "细胞", "基因", "蛋白质", "病毒", "细菌", "治疗", "诊断", "疾病", "症状", "药物",
        "手术", "检查", "分析", "研究", "实验", "临床", "病理", "免疫", "感染", "炎症",
        "癌症", "肿瘤", "心脏", "肺", "肝", "肾", "脑", "血液", "骨骼", "肌肉",
        "cancer", "tumor", "cell", "gene", "protein", "virus", "bacteria", "treatment",
        "diagnosis", "disease", "symptom", "drug", "surgery", "clinical", "pathology",
        "immune", "infection", "inflammation", "heart", "lung", "liver", "kidney", "brain"
    ));

    @Override
    public List<String> extractKeywords(String text) {
        return extractKeywordsWithWeight(text, 20);
    }

    @Override
    public List<String> extractKeywordsWithWeight(String text, int topN) {
        if (!StringUtils.hasText(text)) {
            return new ArrayList<String>();
        }
        
        try {
            // 使用HanLP进行分词和词性标注
            List<Term> terms = HanLP.segment(text);
            
            // 统计词频
            Map<String, Integer> wordCount = new HashMap<String, Integer>();
            Map<String, String> wordPOS = new HashMap<String, String>();
            
            for (Term term : terms) {
                String word = term.word.trim().toLowerCase();
                String pos = term.nature.toString();
                
                // 过滤条件
                if (shouldKeepWord(word, pos)) {
                    wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
                    wordPOS.put(word, pos);
                }
            }
            
            // 计算权重并排序
            List<Map.Entry<String, Integer>> sortedWords = wordCount.entrySet().stream()
                .sorted((e1, e2) -> {
                    // 优先考虑医学关键词
                    boolean isMedical1 = isMedicalKeyword(e1.getKey());
                    boolean isMedical2 = isMedicalKeyword(e2.getKey());
                    
                    if (isMedical1 && !isMedical2) return -1;
                    if (!isMedical1 && isMedical2) return 1;
                    
                    // 按词频排序
                    int freqCompare = e2.getValue().compareTo(e1.getValue());
                    if (freqCompare != 0) return freqCompare;
                    
                    // 按词长排序（较长的词优先）
                    return e2.getKey().length() - e1.getKey().length();
                })
                .limit(topN)
                .collect(Collectors.toList());
            
            List<String> keywords = sortedWords.stream()
                .map(entry -> entry.getKey())
                .collect(Collectors.toList());
            
            log.info("提取关键词完成，共{}个: {}", keywords.size(), keywords);
            return keywords;
            
        } catch (Exception e) {
            log.error("关键词提取失败: {}", e.getMessage());
            return new ArrayList<String>();
        }
    }

    @Override
    public List<String> extractMedicalTerms(String text) {
        if (!StringUtils.hasText(text)) {
            return new ArrayList<String>();
        }
        
        try {
            List<Term> terms = HanLP.segment(text);
            
            Set<String> medicalTerms = new HashSet<String>();
            
            for (Term term : terms) {
                String word = term.word.trim();
                
                // 检查是否为医学术语
                if (isMedicalKeyword(word) && word.length() >= 2) {
                    medicalTerms.add(word);
                }
            }
            
            List<String> result = new ArrayList<String>(medicalTerms);
            log.info("提取医学术语完成，共{}个: {}", result.size(), result);
            return result;
            
        } catch (Exception e) {
            log.error("医学术语提取失败: {}", e.getMessage());
            return new ArrayList<String>();
        }
    }
    
    /**
     * 判断是否应该保留这个词
     */
    private boolean shouldKeepWord(String word, String pos) {
        // 长度过滤
        if (word.length() < 2 || word.length() > 20) {
            return false;
        }
        
        // 停用词过滤
        if (STOP_WORDS.contains(word)) {
            return false;
        }
        
        // 纯数字过滤
        if (word.matches("\\d+")) {
            return false;
        }
        
        // 纯标点符号过滤
        if (word.matches("[\\p{Punct}]+")) {
            return false;
        }
        
        // 词性过滤（保留名词、动词、形容词等）
        if (!MEDICAL_POS.contains(pos.substring(0, 1))) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 判断是否为医学关键词
     */
    private boolean isMedicalKeyword(String word) {
        return MEDICAL_KEYWORDS.contains(word.toLowerCase()) ||
               word.toLowerCase().matches(".*(病|症|炎|癌|瘤|疗|药|医|检|测|析).*");
    }
}